package com.itheima.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.pojo.Permission;
import com.itheima.pojo.Role;
import com.itheima.pojo.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

//将实现类交给spring框架调用
@Component
public class SpringSecurityUserService implements UserDetailsService {
    @Reference  //通过dubbo调用远程服务
    private UserService userService;
    //根据用户名查找用户信息
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //远程调用服务，通过用户名查找用户信息
           User user = userService.findByUsername(username);
           if (user==null){
               //用户不存在，直接返回null
               return null;
           }
               //用户存在，动态为用户授权
        List<GrantedAuthority> list = new ArrayList<>();
               Set<Role> roles = user.getRoles();
           //遍历用户角色集合
               for (Role role : roles) {
                   //将角色关键字存入list
                list.add(new SimpleGrantedAuthority(role.getKeyword()));
                   Set<Permission> permissions = role.getPermissions();
                   //遍历角色的权限集合
                   for (Permission permission : permissions) {
                       //将权限关键字存入list
                       list.add(new SimpleGrantedAuthority(permission.getKeyword()));
                   }
               }
               //将用户名和查询出的密码以及封装了用户角色和权限信息的list 封装到框架提供的User对象中并返回给springsecuity框架
        //框架会自动将密码和用户输入的密码进行比对
        org.springframework.security.core.userdetails.User sercuityUser = new org.springframework.security.core.userdetails.User(username,user.getPassword(),list);

        return sercuityUser;
    }
}
